package net.csdn.business.gateway.config;

import net.csdn.business.gateway.component.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher;

@Configuration
@AutoConfigureBefore(CustomOath2Config.class)
@EnableWebFluxSecurity
public class SecurityWebFluxConfig {

    @Autowired
    private CustomRBACServiceWebFlux customRBACServiceWebFlux;

    @Autowired
    private CustomAccessDeniedHandlerWebFlux customAccessDeniedHandlerWebFlux;

    @Autowired
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http,ReactiveAuthenticationManager reactiveAuthenticationManager,NoOpServerSecurityContextAutoRepository serverSecurityContextRepository) throws Exception {
        http.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/v2/**"))
                .authenticationManager(reactiveAuthenticationManager)
                .securityContextRepository(serverSecurityContextRepository)
                .authorizeExchange(exchange -> exchange
                        .pathMatchers(HttpMethod.OPTIONS).permitAll()
                        //.anyExchange().authenticated()
                        .anyExchange().access(customRBACServiceWebFlux)
                )
                .exceptionHandling()
                .authenticationEntryPoint(customAuthenticationEntryPoint)
                .and()
                .exceptionHandling()
                .accessDeniedHandler(customAccessDeniedHandlerWebFlux)
                .and()
                .formLogin().disable()
                .httpBasic().disable()
                .httpBasic().disable()
                .logout().disable()
                //.addFilterAt(webFilter(), SecurityWebFiltersOrder.AUTHORIZATION)
                .csrf().disable()
        ;
        return http.build();
    }

    @Bean
    ReactiveAuthenticationManager getAuthenticationManager(ResourceServerTokenServices cloudLocalResourceServerTokenServices,ClientDetailsService customClientDetailsService) {
        CustomAuthenticationManagerAdapter adapter=new CustomAuthenticationManagerAdapter(cloudLocalResourceServerTokenServices);
        return adapter;
    }


    @Bean
    NoOpServerSecurityContextAutoRepository getServerSecurityContextRepository(ReactiveAuthenticationManager reactiveAuthenticationManager) {
        NoOpServerSecurityContextAutoRepository serverSecurityContextRepository=new NoOpServerSecurityContextAutoRepository(reactiveAuthenticationManager);
        return serverSecurityContextRepository;
    }



}